home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
TUTORC.ZIP
/
TCCFILES.ZIP
/
TUTSBSTC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-30
|
15KB
|
576 lines
/*
tutsbstc.c
Version for Turbo C
10/30/94
SCP
Adapted from tutprog4.pas, translated into C.
This version is to go with wormietc.c, a version of the wormie
program for Turbo C.
This version of tutsubs is not as complete as the Microsoft C version,
because I did most of my work with the MS version, this is just here
as an example of how to convert to Turbo C.
All the other examples are for Microsoft C.
Steve Pinault scp@ohm.att.com
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <math.h>
#include <conio.h>
#include <graphics.h>
#include <bios.h>
#include <string.h>
#include "tcheadex.h"
//DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
//Procedure SetMCGA; { This procedure gets you into 320x200x256 mode. }
void SetMCGA()
{
asm {
mov ax,0013h
int 10h
}
}
//DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
//Procedure SetText; { This procedure returns you to text mode. }
void SetText()
{
asm {
mov ax,0003h
int 10h
}
}
//{DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
//procedure WaitRetrace; assembler;
/*
This waits until you are in a Verticle Retrace ... this means that all
screen manipulation you do only appears on screen in the next verticle
retrace ... this removes most of the "fuzz" that you see on the screen
when changing the pallette. It unfortunately slows down your program
by "synching" your program with your monitor card ... it does mean
that the program will run at almost the same speed on different
speeds of computers which have similar monitors. In our SilkyDemo,
we used a WaitRetrace, and it therefore runs at the same (fairly
fast) speed when Turbo is on or off.
*/
void WaitRetrace()
{
asm mov dx,3DAh
l1:
asm in al,dx
asm and al,08h
asm jnz l1
l2:
asm in al,dx
asm and al,08h
asm jz l2
}
//DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
//Procedure GetPal(ColorNo : Byte; Var R,G,B : Byte);
void GetPal(char ColorNo, char* R, char* G, char* B)
// This reads the values of the Red, Green and Blue values of a certain
// color and returns them to you.
{
outportb(0x3c7,ColorNo);
*R=inp(0x3c9);
*G=inp(0x3c9);
*B=inp(0x3c9);
}
//DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
//Procedure Pal(ColorNo : Byte; R,G,B : Byte);
void Pal(char ColorNo, char R, char G, char B)
// This sets the Red, Green and Blue values of a certain color
{
outportb(0x3c8,ColorNo);
outportb(0x3c9,R);
outportb(0x3c9,G);
outportb(0x3c9,B);
}
//DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
//Procedure PutPixel (X,Y : Integer; Col : Byte);
// This puts a pixel on the screen by writing directly to memory.
void PutPixel(int X, int Y, char Color, int Where)
{
unsigned char far* VGAScreenPtr;
unsigned int offset;
// VGAScreenPtr=MK_FP(Where,(unsigned)(X+(Y*320)));
offset=(unsigned)X + (unsigned)(Y<<8) + (unsigned)(Y<<6);
VGAScreenPtr=MK_FP(Where,offset);
*VGAScreenPtr=Color;
}
////////////////////////// line //////////////////////////////////
// Procedure line(a,b,c,d,col:integer);
// This draws a line from a,b to c,d of color col. }
void Line(int x1, int y1, int x2, int y2, unsigned char Color)
//////////////////////////////////////////////////////////////////
{
int dx,dy,incr1,incr2,d,x,y,xend,yend,yinc,xinc;
dx=abs(x2-x1);
dy=abs(y2-y1);
if(dx>=dy) // slope < 1
{
if(x1>x2)
{
x=x2; y=y2; xend=x1;
if(dy==0) yinc=0;
else { if(y2>y1) yinc=-1; else yinc=1;}
}
else
{
x=x1; y=y1; xend=x2;
if(dy==0) yinc=0;
else { if(y2>y1) yinc=1; else yinc=-1;}
}
incr1=2*dy; d=incr1-dx; incr2=2*(dy-dx);
PutPixel(x,y,Color,VGA);
while(x<xend)
{
x++;
if(d<0) d+=incr1;
else { y+=yinc; d+=incr2;}
PutPixel(x,y,Color,VGA);
}
}
else
{
if(y1>y2)
{
x=x2; y=y2; yend=y1;
if(dx==0) xinc=0;
else { if(x2>x1) xinc = -1; else xinc = 1;}
}
else
{
x=x1; y=y1; yend=y2;
if(dx==0) xinc=0;
else { if(x2>x1) xinc=1; else xinc = -1;}
}
incr1=2*dx; d=incr1-dy; incr2=2*(dx-dy);
PutPixel(x,y,Color,VGA);
while(y<yend)
{
y++;
if(d<0) d+=incr1;
else { x+=xinc; d+=incr2; }
PutPixel(x,y,Color,VGA);
}
}
}
//////////////////////////////////////////////////////////////////
void Line2(int x1, int y1, int x2, int y2, unsigned char Color, int where)
//////////////////////////////////////////////////////////////////
{
int dx,dy,incr1,incr2,d,x,y,xend,yend,yinc,xinc;
dx=abs(x2-x1);
dy=abs(y2-y1);
if(dx>=dy) // slope < 1
{
if(x1>x2)
{
x=x2; y=y2; xend=x1;
if(dy==0) yinc=0;
else { if(y2>y1) yinc=-1; else yinc=1;}
}
else
{
x=x1; y=y1; xend=x2;
if(dy==0) yinc=0;
else { if(y2>y1) yinc=1; else yinc=-1;}
}
incr1=2*dy; d=incr1-dx; incr2=2*(dy-dx);
PutPixel(x,y,Color,where);
while(x<xend)
{
x++;
if(d<0) d+=incr1;
else { y+=yinc; d+=incr2;}
PutPixel(x,y,Color,where);
}
}
else
{
if(y1>y2)
{
x=x2; y=y2; yend=y1;
if(dx==0) xinc=0;
else { if(x2>x1) xinc = -1; else xinc = 1;}
}
else
{
x=x1; y=y1; yend=y2;
if(dx==0) xinc=0;
else { if(x2>x1) xinc=1; else xinc = -1;}
}
incr1=2*dx; d=incr1-dy; incr2=2*(dx-dy);
PutPixel(x,y,Color,where);
while(y<yend)
{
y++;
if(d<0) d+=incr1;
else { x+=xinc; d+=incr2; }
PutPixel(x,y,Color,where);
}
}
}
////////////////////////// Funny_Line //////////////////////////////////
// Procedure line(a,b,c,d,col:integer);
// This draws a line from a,b to c,d of color col. }
void Funny_Line(int x1, int y1, int x2, int y2, int where)
//////////////////////////////////////////////////////////////////
{
int dx,dy,incr1,incr2,d,x,y,xend,yend,yinc,xinc;
int count = 50;
dx=abs(x2-x1);
dy=abs(y2-y1);
if(dx>=dy) // slope < 1
{
if(x1>x2)
{
x=x2; y=y2; xend=x1;
if(dy==0) yinc=0;
else { if(y2>y1) yinc=-1; else yinc=1;}
}
else
{
x=x1; y=y1; xend=x2;
if(dy==0) yinc=0;
else { if(y2>y1) yinc=1; else yinc=-1;}
}
incr1=2*dy; d=incr1-dx; incr2=2*(dy-dx);
PutPixel(x,y,(char)count,where);
count++;
if(count==101)count=50;
while(x<xend)
{
x++;
if(d<0) d+=incr1;
else { y+=yinc; d+=incr2;}
PutPixel(x,y,(char)count,where);
count++;
if(count==101)count=50;
}
}
else
{
if(y1>y2)
{
x=x2; y=y2; yend=y1;
if(dx==0) xinc=0;
else { if(x2>x1) xinc = -1; else xinc = 1;}
}
else
{
x=x1; y=y1; yend=y2;
if(dx==0) xinc=0;
else { if(x2>x1) xinc=1; else xinc = -1;}
}
incr1=2*dx; d=incr1-dy; incr2=2*(dx-dy);
PutPixel(x,y,(char)count,where);
count++;
if(count==101)count=50;
while(y<yend)
{
y++;
if(d<0) d+=incr1;
else { x+=xinc; d+=incr2; }
PutPixel(x,y,(char)count,where);
count++;
if(count==101)count=50;
}
}
}
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure PalPlay;
void PalPlay()
{
// This procedure mucks about with our "virtual pallette", then shoves it
// to screen.
char Tmp[3];
// This is used as a "temporary color" in our pallette }
int i,loop1;
// This copies color 200 from our virtual pallette to the Tmp variable:
Tmp[0]=Pall[200][0];
Tmp[1]=Pall[200][1];
Tmp[2]=Pall[200][2];
// This moves the entire virtual pallette up one color:
for(i=200;i>0;i--)
{
Pall[i][0]=Pall[i-1][0];
Pall[i][1]=Pall[i-1][1];
Pall[i][2]=Pall[i-1][2];
}
// This copies the Tmp variable to the bottom of the virtual pallette:
Pall[0][0]=Tmp[0];
Pall[0][1]=Tmp[1];
Pall[0][2]=Tmp[2];
WaitRetrace();
for(loop1=1;loop1<256;loop1++)
Pal((unsigned char)loop1,Pall[loop1][0],Pall[loop1][1],Pall[loop1][2]);
}
//////////////////////////////////////////////////////////////////////
// More general purpose version of the above routine, used in tut7.c:
// Moves all colors up one. Note fmemmove is (dest,src)
void rotatepal(char locpal[][3], int start, int end)
{
char Tmp[3];
int loop1;
int number=end-start;
_fmemmove(Tmp,locpal[end],3);
_fmemmove(locpal[start+1],locpal[start],number*3);
_fmemmove(locpal[start],Tmp,3);
WaitRetrace();
for(loop1=start;loop1<end+1;loop1++)
Pal((unsigned char)loop1,locpal[loop1][0],locpal[loop1][1],
locpal[loop1][2]);
}
// DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure GrabPallette;
void GrabPallette()
{
int loop1;
for(loop1=0;loop1<256;loop1++)
{
GetPal((unsigned char)loop1,&Pall2[loop1][0],&Pall2[loop1][1],&Pall2[loop1][2]);
}
}
// DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure Blackout;
// This procedure blackens the screen by setting the pallette values of
// all the colors to zero.
void Blackout()
{
int loop1;
WaitRetrace();
for(loop1=0;loop1<256;loop1++)
{
Pal((unsigned char)loop1,0,0,0);
}
}
// DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure Fadeup;
// This procedure slowly fades up the new screen }
void FadeUp()
{
int loop1,loop2;
char Tmp[3]; // This is temporary storage for the values of a color
// A color value for Red, green or blue is 0 to 63, so this loop only
// need be executed a maximum of 64 times:
for(loop1=0;loop1<64;loop1++)
{
WaitRetrace();
for(loop2=0;loop2<256;loop2++)
{
GetPal((unsigned char)loop2,&Tmp[0],&Tmp[1],&Tmp[2]);
// If the Red, Green or Blue values of color loop2 are less then they
// should be, increase them by one:
if(Tmp[0]<Pall2[loop2][0]) Tmp[0]++;
if(Tmp[1]<Pall2[loop2][1]) Tmp[1]++;
if(Tmp[2]<Pall2[loop2][2]) Tmp[2]++;
// Set the new, altered pallette color:
Pal((unsigned char)loop2,Tmp[0],Tmp[1],Tmp[2]);
}
}
}
// DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure FadeDown;
// This procedure fades the screen out to black. }
void FadeDown()
{
int loop1,loop2;
char Tmp[3]; // This is temporary storage for the values of a color
// A color value for Red, green or blue is 0 to 63, so this loop only
// need be executed a maximum of 64 times:
for(loop1=0;loop1<64;loop1++)
{
WaitRetrace();
for(loop2=0;loop2<256;loop2++)
{
GetPal((unsigned char)loop2,&Tmp[0],&Tmp[1],&Tmp[2]);
// If the Red, Green or Blue values of color loop2 are not yet zero,
// then, decrease them by one. }
if(Tmp[0]>0) Tmp[0]--;
if(Tmp[1]>0) Tmp[1]--;
if(Tmp[2]>0) Tmp[2]--;
// Set the new, altered pallette color:
Pal((unsigned char)loop2,Tmp[0],Tmp[1],Tmp[2]);
}
}
}
// DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure RestorePallette;
// This procedure restores the origional pallette
void RestorePallette()
{
int loop1;
WaitRetrace();
for(loop1=0;loop1<256;loop1++)
Pal ((unsigned char)loop1,Pall2[loop1][0],Pall2[loop1][1],Pall2[loop1][2]);
}
///////////////////////////////////////////////////////////////////////////////
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure Cls (Col : Byte; Where:Word);
// This clears the screen to the specified color, on the VGA or on the
// virtual screen
// Argument Where will be either VGA or Vaddr: the SEG of the Screen Pointer.
void Cls(char Color, int Where)
{
//Fillchar (Mem [where:0],64000,col);
unsigned char far* ScreenPtr;
ScreenPtr=MK_FP(Where,0x0);
_fmemset(ScreenPtr,Color,(unsigned int)64000);
}
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure Flip;
// { This flips the virtual screen to the VGA screen. }
void Flip()
{
unsigned char far* ScreenPtr;
ScreenPtr=MK_FP(VGA,0x0);
_fmemmove(ScreenPtr,VirtPtr,(unsigned int)64000);
}
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// procedure flip(source,dest:Word);
// { This copies the entire screen at "source" to destination }
void Flip2(int Source, int Dest)
{
asm {
push ds
mov ax, Dest
mov es, ax
mov ax, Source
mov ds, ax
xor si, si
xor di, di
mov cx, 32000
rep movsw
pop ds
}
}
//int random(int x)
//{
// return (int)((long)(rand()*(long)x)/(long)32767);
//}
// DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
// Function rad (theta : real) : real;
// This calculates the degrees of an angle
// rad := theta * pi / 180
float rad(float theta)
{
return theta*PI/(float)180.0;
}
int round(float x)
{
if(x>=0)
return (int)(x+0.5);
else
return (int)(x-0.5);
}
//////////////// SetUpVirtual /////////////////////////
// Sets up pointers to 2 virtual screens
void SetUpVirtual()
{
VirtPtr=&Virtual[0];
Vaddr = FP_SEG(VirtPtr);
VirtPtr=&Virtual2[0];
Vaddr2 = FP_SEG(VirtPtr);
}
//{DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
//Procedure Hline (x1,x2,y:word;col:byte;where:word); assembler;
// { This draws a horizontal line from x1 to x2 on line y in color col }
void Hline(int x1, int x2, int y, char col, int where)
{
asm mov ax,where
asm mov es,ax
asm mov ax,y
asm mov di,ax
asm shl ax,8
asm shl di,6
asm add di,ax
asm add di,x1
asm mov al,col
asm mov ah,al
asm mov cx,x2
asm sub cx,x1
asm shr cx,1
asm jnc lstart
asm stosb
lstart :
asm rep stosw
}
// {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
// Procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
// This puts a pixel on the screen by writing directly to memory. }
// Assembly version
void PutPixel2(int x, int y, char col, int where)
{
asm {
mov ax,where
mov es,ax
mov bx,x
mov dx,y
mov di,bx
mov bx, dx // {; bx = dx}
shl dx, 8
shl bx, 6
add dx, bx // {; dx = dx + bx (ie y*320)}
add di, dx // {; finalise location}
mov al, col
stosb
}
}